package com.bjy.qa.agent.tester.handler.perf;

import com.alibaba.fastjson.JSONObject;
import com.bjy.qa.agent.enumtype.RunStatus;
import com.bjy.qa.agent.tester.TaskManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Semaphore;

/**
 * 性能测试任务启动线程（Tester 启动各个子任务的线程）
 */
public class PerfTesterTaskBootThread extends Thread {
    private final Logger log = LoggerFactory.getLogger(PerfTesterTaskBootThread.class);

    public final static String PERF_TEST_TASK_BOOT_PRE = "perf-tester-test-task-boot-rid%s-cid%s"; // 占用符逻辑参考
    private Semaphore finished = new Semaphore(0); // 判断线程是否结束
    private Boolean forceStop = false; // 强制停止标记
    private JSONObject jsonObject; // 待执行的任务信息
    private PerfTesterStepHandler perfTesterStepHandler; // Tester 步骤执行器（包含状态信息）
    private PerfTesterRunStepThread runStepThread; // 测试步骤线程
    private int resultId = 0; // 测试结果id（0表示DEBUGGING）
    private int caseId = 0; // 测试用例id（0表示DEBUGGING）

    /**
     * 格式化线程名称
     * @param baseFormat 占用符逻辑参考
     * @return 格式化后的线程名称
     */
    public String formatThreadName(String baseFormat) {
        return String.format(baseFormat, this.resultId, this.caseId);
    }

    /**
     * 性能 线程构造
     */
    public PerfTesterTaskBootThread() {
        this.setName(this.formatThreadName(PERF_TEST_TASK_BOOT_PRE));
        this.setDaemon(true);
    }

    /**
     * 正常线程构造
     * @param jsonObject 待执行的任务数据
     * @param perfTesterStepHandler Tester 步骤执行器（包含状态信息）
     */
    public PerfTesterTaskBootThread(JSONObject jsonObject, PerfTesterStepHandler perfTesterStepHandler) {
        this.perfTesterStepHandler = perfTesterStepHandler;
        this.jsonObject = jsonObject;
        this.resultId = jsonObject.getInteger("rid") == null ? 0 : jsonObject.getInteger("rid");
        this.caseId = jsonObject.getInteger("cid") == null ? 0 : jsonObject.getInteger("cid");

        // 比如：perf-tester-test-task-boot-rid100-cid200
        this.setName(String.format(PERF_TEST_TASK_BOOT_PRE, resultId, caseId));
        this.setDaemon(true); // 设置为守护线程
    }

    /**
     * 等待线程结束
     * @throws InterruptedException
     */
    public void waitFinished() throws InterruptedException {
        finished.acquire();
    }

    /**
     * 获取执行的任务数据
     * @return
     */
    public JSONObject getJsonObject() {
        return jsonObject;
    }

    /**
     * 获取 PerfTester 步骤执行器（包含状态信息）
     * @return
     */
    public PerfTesterStepHandler getPerfTesterStepHandler() {
        return perfTesterStepHandler;
    }

    /**
     * 获取运行步骤的线程
     * @return
     */
    public PerfTesterRunStepThread getRunStepThread() {
        return runStepThread;
    }

    /**
     * 设置 测试结果id
     * @param resultId 测试结果id
     * @return
     */
    public PerfTesterTaskBootThread setResultId(int resultId) {
        this.resultId = resultId;
        return this;
    }

    /**
     * 获取 测试结果id
     * @return
     */
    public int getResultId() {
        return resultId;
    }

    /**
     * 设置 测试用例id
     * @param caseId 测试用例id
     * @return
     */
    public PerfTesterTaskBootThread setCaseId(int caseId) {
        this.caseId = caseId;
        return this;
    }

    /**
     * 获取 测试用例id
     * @return
     */
    public int getCaseId() {
        return caseId;
    }

    /**
     * 获取 强制停止标记
     * @return
     */
    public Boolean getForceStop() {
        return forceStop;
    }

    /**
     * 线程 run
     * 1. 创建 TesterRunStepThread 线程
     * 2. 启动所有子线程
     */
    @Override
    public void run() {
        try {
            runStepThread = new PerfTesterRunStepThread(this); // 正常运行步骤的线程
            TaskManager.startChildThread(this.getName(), runStepThread); // 启动所有子线程

            // 等待所有子线程结束
            while (runStepThread.isAlive()) {
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            log.error("任务异常，中断：{}", e.getMessage());
            perfTesterStepHandler.setResultDetailStatus(RunStatus.BROKEN); // 设置任务状态为失败
            forceStop = true; // 强制停止
        } finally {
            perfTesterStepHandler.sendStatus(); // 发送任务状态
            perfTesterStepHandler.closeDriver(); // 关闭 driver
            finished.release(); // 释放信号量
            TaskManager.clearTerminatedThreadByKey(this.getName()); // 清除已终止的线程
        }
    }
}
